package kn.pulldata.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import kn.pulldata.common.RabbitMqCon;
import kn.pulldata.entity.DataSourceStatus;
import kn.pulldata.entity.SchemeSourceRelation;
import kn.pulldata.entity.UserContentInfo;
import kn.pulldata.mapper.OrganizationAccountMapper;
import kn.pulldata.mapper.SchemeSourceRelationMapper;
import kn.pulldata.mapper.UserContentInfoMapper;
import kn.pulldata.mq.SimpleUserCache;
import kn.pulldata.req.*;
import kn.pulldata.service.DataSourceStatusService;
import kn.pulldata.service.ExternalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@Slf4j
public class ExternalServiceImpl implements ExternalService {


    @Autowired
    private OrganizationAccountMapper organizationAccountMapper;

    private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private DataSourceStatusService dataSourceStatusService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private UserContentInfoMapper userContentInfoMapper;

    @Override
    public void pushWebSocket(InfoPushData infoPushData) {

        Integer cityId = infoPushData.getCityId();
        log.info("收到监测方案id{}数据",cityId);
        // 校验数据源配置是否存在

        // 存在则继续
        DataSourceStatus one = dataSourceStatusService.getOne(
                Wrappers.<DataSourceStatus>lambdaQuery().eq(DataSourceStatus::getSchemeId, cityId)
        );
        if(Objects.isNull(one)){
            log.info("监测方案{}未配置数据源",cityId);
            return;
        }
        Integer orgaId = infoPushData.getOrgaId();
        if(Objects.isNull(orgaId)){
            log.info("机构id{}为空",orgaId);
            return;
        }
        List<Integer> userIdList = SimpleUserCache.get(orgaId);
        if (userIdList == null) {
            userIdList = organizationAccountMapper.selectUserIdListByOrgId(orgaId);
            if (userIdList == null || userIdList.isEmpty()) {
                log.info("用户id集合为空");
                return;
            }
            SimpleUserCache.put(orgaId, userIdList);
        }
        MsgReq req = new MsgReq();
        req.setTitle(infoPushData.getTitle());
        req.setAbstracts(infoPushData.getAbstracts());
        Date releaseTime = infoPushData.getReleaseTime();
        if(Objects.nonNull(releaseTime)){
            String format = simpleDateFormat.format(releaseTime);
            req.setReleaseTime(format);
        }
        req.setSource(infoPushData.getSource());
        req.setMediaLink(infoPushData.getMediaLink());
        req.setAuthor(infoPushData.getSourceAuthor());
        req.setWebsite(infoPushData.getWebsite());
        req.setSourceId(one.getSourceId());
        req.setCurrentTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
        List<String> userList = new ArrayList<>();
        ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();
        for (Integer userId : userIdList) {
            // 当前用户的数据源是否暂停
            String key = "WDG:" + userId +"_"+ orgaId +"_"+ one.getSourceId();
            String val = stringStringValueOperations.get(key);
            if(Objects.isNull(val)){
                //log.info("机构用户未开启：{}",key);
                continue;
            }
            if("1".equals(val)){
                userList.add("WDG"+ userId + orgaId);
            }else if("0".equals(val)){
                // 暂停：将数据存入数据库中
                UserContentInfo userContentInfo = BeanUtil.copyProperties(req, UserContentInfo.class);
                userContentInfo.setUserId(userId);
                userContentInfo.setSourceId(one.getSourceId());
                userContentInfoMapper.insert(userContentInfo);
            }else {
                log.info("机构用户状态错误");
            }
        }
        if(! userList.isEmpty()){
            MsgVO msgVO = new MsgVO();
            msgVO.setUserFlagList(userList);
            msgVO.setPushContent(JSONUtil.toJsonStr(req));
            // 推送
            String key = "customer_pc_push_" +req.getSourceId() % 9;
            rabbitTemplate.convertAndSend(RabbitMqCon.WUDAOGANG_KEY_EXCHANGE,key,JSONUtil.toJsonStr(msgVO));
            log.info("成功给{}推送{}数据",userList,key);
        }
    }

    @Override
    public String action(ActionReq req) {
        ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();
        String key = "WDG:" + req.getUserId() +"_"+ req.getOrgId() +"_"+ req.getSourceId();
        stringStringValueOperations.set(key, String.valueOf(req.getIsRun()));
        if(Objects.isNull(req.getId())){
            return null;
        }
        DataSourceStatus byId = dataSourceStatusService.getById(req.getId());
        if(Objects.isNull(byId)){
            throw new RuntimeException("id不存在");
        }
        DataSourceStatus entity = new DataSourceStatus();
        entity.setId(req.getId());
        entity.setIsRun(req.getIsRun());
        if(1 == (req.getIsRun())){
            if(Objects.nonNull(byId.getPauseTime())){
                // 启动 查询当前用户的大于暂停时间的数据
                List<UserContentInfo> userContentInfos = userContentInfoMapper.selectList(Wrappers.<UserContentInfo>lambdaQuery()
                        .eq(UserContentInfo::getUserId, req.getUserId())
                        .eq(UserContentInfo::getSourceId, req.getSourceId())
                        .gt(UserContentInfo::getCreateTime, byId.getPauseTime()));
                // 推送
                MsgVO msgVO = new MsgVO();
                msgVO.setUserFlagList(Collections.singletonList("WDG" + req.getUserId() + req.getOrgId()));
                if(! userContentInfos.isEmpty()){
                    for (UserContentInfo userContentInfo : userContentInfos) {
                        MsgReq msgReq = BeanUtil.copyProperties(userContentInfo, MsgReq.class);
                        msgReq.setSourceId(byId.getSourceId());
                        msgReq.setCurrentTime(userContentInfo.getCreateTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
                        msgVO.setPushContent(JSONUtil.toJsonStr(msgReq));
                        // 推送
                        String sendKey = "customer_pc_push_" +byId.getSourceId() % 9;
                        rabbitTemplate.convertAndSend(RabbitMqCon.WUDAOGANG_KEY_EXCHANGE,sendKey,JSONUtil.toJsonStr(msgVO));
                        log.info("【暂停-开始】数据{}已经推送",msgReq.getWebsite());
                    }
                }
            }
        }else {
            entity.setPauseTime(LocalDateTime.now());
        }
        dataSourceStatusService.updateById(entity);
        return "ok";
    }

    @Override
    public DataSourceStatus add(AddReq req) {
        DataSourceStatus db = dataSourceStatusService.getOne(
                Wrappers.<DataSourceStatus>lambdaQuery().eq(DataSourceStatus::getSourceId, req.getSourceId())
        );
        if(Objects.nonNull(db)){
            throw new RuntimeException("数据源id不能重复");
        }
        ActionReq actionReq = new ActionReq();
        actionReq.setIsRun(1);
        actionReq.setOrgId(req.getOrgId());
        actionReq.setUserId(req.getUserId());
        actionReq.setSourceId(req.getSourceId());

        action(actionReq);

        DataSourceStatus dataSourceStatus = new DataSourceStatus();
        dataSourceStatus.setUserId(req.getUserId());
        dataSourceStatus.setIsRun(1);
        dataSourceStatus.setSourceId(req.getSourceId());
        dataSourceStatus.setSourceName(req.getSourceName());
        dataSourceStatus.setUserId(req.getUserId());
        dataSourceStatus.setSchemeId(req.getSchemeId());
        dataSourceStatus.setSchemeName(req.getSchemeName());
        dataSourceStatusService.save(dataSourceStatus);
        return dataSourceStatus;
    }

    @Autowired
    private SchemeSourceRelationMapper schemeSourceRelationMapper;

    @Override
    public List<SchemeSourceRelation> search(Integer dataSoureId) {
        return schemeSourceRelationMapper.selectList(
                Wrappers.<SchemeSourceRelation>lambdaQuery()
                        .eq(SchemeSourceRelation::getSourceId, dataSoureId)
        );
    }

    @Override
    public Boolean update(UpdateReq req) {
        DataSourceStatus byId = dataSourceStatusService.getById(req.getId());
        if(Objects.isNull(byId)){
            throw new RuntimeException("数据不存在");
        }
        if(byId.getSourceName().equals(req.getSourceName())){
            throw new RuntimeException("数据源名称不能重复");
        }
        DataSourceStatus dataSourceStatus = BeanUtil.copyProperties(req, DataSourceStatus.class);
        dataSourceStatus.setId(req.getId());
        return dataSourceStatusService.updateById(dataSourceStatus);

    }

    @Override
    public List<DataSourceStatus> list() {
        return dataSourceStatusService.list();

    }

    @Override
    public Boolean delete(Integer id, Integer orgId) {
        DataSourceStatus byId = dataSourceStatusService.getById(id);
        if(Objects.isNull(byId)){
            throw new RuntimeException("数据不存在");
        }
        redisTemplate.delete("WDG:" + byId.getUserId() +"_"+ orgId +"_"+ byId.getSourceId());
        return dataSourceStatusService.removeById(id);
    }


}
